/*******************************************************************************
 * Copyright 2009 Omnidroid - http://code.google.com/p/omnidroid
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *******************************************************************************/
package edu.nyu.cs.omnidroid.app.controller.datatypes;

import android.util.Log;
import edu.nyu.cs.omnidroid.app.context.GlobalAttributes;
import edu.nyu.cs.omnidroid.app.controller.datatypes.OmniText.Filter;
import edu.nyu.cs.omnidroid.app.controller.util.DataTypeValidationException;

/**
 * Boolean generic data type to allow for attributes to be selected in a filter.
 * 
 */
public class OmniBoolean extends DataType {
  static final String TAG = "OmniBoolean";
  private Boolean value;
  /* Assigned when a filter is loaded from the database via
   * the constructor(String).
   * Use this key to get the value from the GlobalAttributes (context)
   */
  private String GlobKey;

  /* data type name to be stored in db */
  public static final String DB_NAME = "Boolean";

  public enum Filter implements DataType.Filter {
	  EQUALS("equals");
	  
	  public final String displayName;
	  
	  Filter(String displayName) {
	    	this.displayName = displayName; 
	  }
  }
  
  public OmniBoolean(Boolean value) {
    this.value = value;
  }
  
  public OmniBoolean(String value) {
	  int res;
		String intermediate;
	/*
	 * Instantiation
	 */
	if ((res = value.indexOf("=")) != -1) {
		this.GlobKey = value.substring(0, res);
		intermediate = value.substring(res+1, value.length());
		this.value = Boolean.parseBoolean(intermediate);
		Log.i(TAG, "Instance [" + value + "] Parsed [" + this.GlobKey + "] = [" + this.value.toString() + "] [" + intermediate + "]");
	/*
	 * Assume it's a filter
	 */
	} else if ((res = value.indexOf("filter:")) != -1) {
		this.GlobKey = null;
		intermediate = value.substring(7, value.length());
		this.value = Boolean.parseBoolean(intermediate);
		Log.i(TAG, "Filter [" + value + "] Parsed [" + this.GlobKey + "] = [" + this.value.toString() + "] [" + intermediate + "]");
	} else {
		
		Log.w(TAG, "Invalid OmniBoolean: [" + value + "]");
	}
  }
  
  public OmniBoolean(Object value) {
	 this.value = Boolean.parseBoolean(value.toString());
  }

  @Override
  public String getValue() {
    return value.toString();
  }

  /**
   * 
   * @param str
   *          the filter name.
   * @return Filter
   * @throws IllegalArgumentException
   *           when the filter with the given name does not exist.
   */
  public static Filter getFilterFromString(String str) throws IllegalArgumentException {
    return Filter.valueOf(str.toUpperCase());
  }
  
  /*
   * (non-Javadoc)
   * 
   * @see edu.nyu.cs.omnidroid.core.datatypes.DataType#matchFilter(DataType.Filter, DataType)
   */
  public boolean matchFilter(DataType.Filter filter, DataType userDefinedValue)
      throws IllegalArgumentException {
    if (!(filter instanceof Filter)) {
      throw new IllegalArgumentException("Invalid filter type '" + filter.toString()
          + "' provided.");
    }
    if(userDefinedValue instanceof OmniBoolean){
      return matchFilter((Filter) filter, (OmniBoolean) userDefinedValue);
    }
    throw new IllegalArgumentException("Matching filter not found for the datatype " + 
        userDefinedValue.getClass().toString()+ ". ");
  }

  public boolean matchFilter(Filter filter, OmniBoolean comparisonValue) {
    switch (filter) {
    case EQUALS:
    	return (comparisonValue.value == this.value);
    	
    	// Maybe this should be using comparisonValue.GlobKey
    	// and == to this.value instead
//      Boolean globValue = (Boolean)GlobalAttributes.getGlob(this.GlobKey);
//      Log.i(TAG, "matchFilter [" + globValue + "] == [" + comparisonValue.value + "]");
//      return (globValue == comparisonValue.value);
      
//      Boolean globValue = (Boolean)GlobalAttributes.getGlob(comparisonValue.GlobKey);
//      Log.i(TAG, "matchFilter [" + globValue + "] == [" + this.value + "]");
//      return (globValue == this.value);
      //return (value == comparisonValue.value);
    default:
      return false;
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see edu.nyu.cs.omnidroid.core.datatypes.DataType#validateUserDefinedValue(java.lang.String,
   * java.lang.String)
   */
  public static void validateUserDefinedValue(DataType.Filter filter, String userInput)
      throws DataTypeValidationException, IllegalArgumentException {
    if (!(filter instanceof Filter)) {
      throw new IllegalArgumentException("Invalid filter type '" + filter.toString()
          + "' provided.");
    }
    if (userInput == null) {
      throw new DataTypeValidationException("The user input cannot be null.");
    }
  }

  /**
   * Indicates whether or not the given filter is supported by the data type.
   * 
   * @param filter
   * @return true if the filter is supported, false otherwise.
   */
  public static boolean isValidFilter(String filter) {
    try {
      getFilterFromString(filter);
    } catch (IllegalArgumentException e) {
      return false;
    }
    return true;
  }

  /**
   * Encoding of filter to be stored in the database
   */
  @Override
  public String toString() {
    return this.GlobKey + "=" + this.value.toString();
  }


}